Skip to content

Trace EIP-8130 transactions (type 0x79) - #35

Merged
sduchesneau merged 13 commits into
release/1.xfrom
feature/aa-transaction-type
Oct 21, 2026
Merged

sduchesneau merged 13 commits into
release/1.xfrom
feature/aa-transaction-type

Conversation

@sduchesneau

@sduchesneau sduchesneau commented Oct 20, 2026 •

Copy link
Copy Markdown

Implements the plan in #24 on top of streamingfast/evm-firehose-tracer-rs#38 and streamingfast/reth#74, using the block model from streamingfast/firehose-ethereum#262.

  • OpPreTxAdjust fills account_abstraction_trx_input from the envelope (nonce key, resolved payer, validity window, metadata, delegation, phases), sets v/r/s from sender_auth and to to empty, and installs RootJournalReasons: payer GasBuy / GasRefund, then the fee vaults and the beneficiary RewardTransactionFee, in the order settle_fees credits them. Keystore account changes (Zenith only) stop the node with a clear error; Trace the Keystore account changes #37 records them.
  • An open payer whose signature does not recover is left to the executor, which rejects the transaction before its root call; the block is discarded instead of the node panicking.
  • OpPostTxExtras records committed_phases, counted from Eip8130PhaseStatuses::peek() (a copy of the statuses, read before the receipt builder takes them), and skips the OP vault emissions, which the journal already carries for this type.
  • base-firehose-tests: run_block runs signed transactions on an in-code genesis. The eip8130 tests on an Everest genesis cover a failed middle phase, a failure in the first phase, a named payer with a nonce channel, nonce-free mode, a delegation, a call refused for lack of new-account gas, a payer that is also the beneficiary, and an open payer signature that does not recover, with BlockInvariants on each block.

Uses firehose-tracer 5.7.0 from crates.io and the streamingfast/reth tag base-v2.5.2.8-fh3.1-2 (streamingfast/reth#74, base#75 and base#79).

Not covered yet: the Docker firehose_everest system test and the in-process Everest action tests.

@sduchesneau
sduchesneau added this pull request to stack #38 October 20, 2026 20:09
@sduchesneau
sduchesneau marked this pull request as ready for review October 20, 2026 20:14
@sduchesneau
sduchesneau requested review from maoueh and removed request for UlysseCorbeil October 20, 2026 21:06

@maoueh maoueh left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving with small things to check.

Comment on lines +102 to +119
/// Number of phases that committed in the statuses recorded by the most recent
/// [`Self::set`] on this thread, leaving them in place for [`Self::take`]. Phases stop at
/// the first revert, so this is the count of leading `0x01` statuses. Returns 0 in `no_std`
/// builds.
#[cfg(feature = "std")]
pub fn committed_phases() -> u64 {
PHASE_STATUSES
.with(|cell| cell.borrow().iter().take_while(|status| **status == 0x01).count() as u64)
}

/// Number of phases that committed in the statuses recorded by the most recent
/// [`Self::set`] on this thread, leaving them in place for [`Self::take`]. Phases stop at
/// the first revert, so this is the count of leading `0x01` statuses. Returns 0 in `no_std`
/// builds.
#[cfg(not(feature = "std"))]
pub const fn committed_phases() -> u64 {
0
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could think of upstreaming that, also they seem to use "short" name for everything take, push, etc so I would say that count seems more appropriate if we suggest an upstream modification.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or a plain borrow and we count outside of it, also count is indeed "wrong", would need to be committed_count or something like

Comment on lines +239 to +243
panic!(
"Firehose cannot trace transaction {}: an EIP-8130 transaction reached the EVM \
without its envelope",
tx_event.hash
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trace has specialized "panic" which logs block number/trx hash/tracer state in general, can you look to check if they could be used here instead of plain panics (it's not clear but probably it reachable)

The executor rejects such a transaction and the block is discarded. Also counts the
committed phases in the hook from a copy of the statuses.
…nsaction-type

# Conflicts:
#	CHANGELOG.sf.md
#	Cargo.lock
#	Cargo.toml
Picks up the fix for an account whose balance changes twice in one journal read.
Lists the fee credits in settlement order, makes the hook public, moves the harness
imports to the top and drops formatting changes to untouched lines.
A payer that is also the beneficiary, nonce-free mode, a failure in the first phase
and a call refused for lack of new-account gas.
@sduchesneau
sduchesneau merged commit b7fb277 into release/1.x Oct 21, 2026
2 checks passed
@sduchesneau
sduchesneau deleted the feature/aa-transaction-type branch October 21, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants